package rmmk.algorithms.similarityMeasures;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import rmmk.algorithms.similarityMeasures.abstraction.AbstractSimilarityMeasure;
import rmmk.framework.datasources.Document;

/**
 * Klasa odpowiedzialna za przechowywanie, wyliczanie oraz cachowanie miar podobienstwa dokumentow 
 * @author Marcin
 *
 */
public class SimilarityMeasureManager {
	
	Logger logger = LoggerFactory.getLogger(SimilarityMeasureManager.class);
	private HashMap<Document, Double[]> cache = new HashMap<>();
	private Vector<AbstractSimilarityMeasure> similarityMeasures = new Vector<>();

	/**
	 * Dodaje cechy do obliczeń
	 * @param features
	 */
	public void addMeasure(AbstractSimilarityMeasure... measures) {
		for (AbstractSimilarityMeasure f : measures)
			this.addMeasure(f);
	}
	
	public void addMeasure(ArrayList<AbstractSimilarityMeasure> measures) {
		for (AbstractSimilarityMeasure f : measures)
			this.addMeasure(f);
	}

	/**
	 * Dodaje pojedyńczą miare podobienstwa do obliczeń
	 * @param feature
	 */
	public void addMeasure(AbstractSimilarityMeasure measure) {
		this.cache.clear();
		
		this.similarityMeasures.add(measure);
	}

	/**
	 * Wylicza wektor miar podobienstw dla pojedyńczego dokumentu
	 * @param document 
	 * @return
	 **/
	public Double[] calculateSimilarityMeasureFor(Document input, Document document)
	{
		if(this.cache.containsKey(document)) return this.cache.get(document);
		
		int vectorLenght = 0;
		for(AbstractSimilarityMeasure asm : this.similarityMeasures)
			vectorLenght+= asm.getSimilarityMeasureSize();
		
		Double[] resp = new Double[vectorLenght];
		
		int i = 0;
		for(AbstractSimilarityMeasure afe : this.similarityMeasures){
			Double[] val = afe.calculate(input,document);
			
			for(Double d : val)
				resp[i++] = d;
		}
		
		this.cache.put(document, resp);
		
		return resp;
	}

	/**
	 * Zwraca aktualną długość wektora miar podobienstw
	 * @return
	 */
	public int getVectorLenght()
	{
		int sum = 0;
		
		for(AbstractSimilarityMeasure asm : this.similarityMeasures)
			sum += asm.getSimilarityMeasureSize();
		
		return sum;
	}
	
	public Vector<AbstractSimilarityMeasure> getSimilarityMeasures() {
		return similarityMeasures;
	}
}
